package com.lsh.payment.core.strategy.payment;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import com.lsh.payment.core.constant.BusinessConstant;
import com.lsh.payment.core.model.payenum.PayWay;
import com.lsh.payment.core.strategy.config.AliPayConfig;
import com.lsh.payment.core.strategy.vo.alipay.AliPrePayResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.text.MessageFormat;
import java.util.Map;

import static com.lsh.payment.core.constant.BusinessConstant.ALIPAY;
import static com.lsh.payment.core.constant.BusinessConstant.STRATEGY_BEAN_NAME_PREFIX;

/**
 *   
 *  支付宝app支付 
 * Project Name: lsh-payment
 *
 * @author peter
 * @date 16/10/30
 * 北京链商电子商务有限公司
 * Package
 * desc:
 */
@Component(STRATEGY_BEAN_NAME_PREFIX + ALIPAY)
public class AlipayStrategy implements PayStrategy<AliPrePayResponse> {

    private static Logger logger = LoggerFactory.getLogger(AlipayStrategy.class);

    @Value("${ali.notify.url}")
    private String notifyUrl;

    @Override
    public AliPrePayResponse generatePayParams(int payType, final Map<String, String> paramMap) {

        String payWay = paramMap.get(BusinessConstant.PAY_WAY);
        //APP和H5参数不一致
        if (payWay.equals(PayWay.IOS.getName()) || payWay.equals(PayWay.ANDROID.getName())) {

            return alipayApp(paramMap);
        } else if (payWay.equals(PayWay.H5.getName())) {

            return alipayH5(paramMap);
        } else {
            logger.info("pay_way para is : " + payWay);
            return null;
        }
    }


    /**
     * 支付宝支付下单
     *
     * @param paramMap 参数
     * @return 返回结果
     */
    private AliPrePayResponse alipayH5(final Map<String, String> paramMap) {
        AliPrePayResponse aliPrePayResponse = new AliPrePayResponse();

        AlipayClient alipayClient = new DefaultAlipayClient(AliPayConfig.ALIPAY_URL, AliPayConfig.app_id, AliPayConfig.private_key, AliPayConfig.FORMAT, AliPayConfig.input_charset, AliPayConfig.public_key, AliPayConfig.sign_type_2);

        AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();
        //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
//        model.setBody(AliPayConfig.GOODS_APP_DETAIL);
        model.setSubject(paramMap.get("payPaymentNo"));
        model.setOutTradeNo(paramMap.get("payPaymentNo"));
        model.setTimeoutExpress(AliPayConfig.TIMEOUT_EXPRESS);
        model.setTotalAmount(paramMap.get("payAmount"));
        model.setProductCode(AliPayConfig.PRODUCT_CODE_WAP);

        alipayRequest.setBizModel(model);
        alipayRequest.setNotifyUrl(notifyUrl);
        alipayRequest.setReturnUrl(paramMap.get("returnUrl"));
        //构造请求(签名)
        String alipayRequestUrl;
        try {
            AlipayTradeWapPayResponse response = alipayClient.pageExecute(alipayRequest);
            logger.info(response.isSuccess() + "," + JSON.toJSONString(response));
            if (response.isSuccess()) {
                alipayRequestUrl = response.getBody();
            } else {
                throw new AlipayApiException("alipay exception");
            }
        } catch (AlipayApiException e) {
            logger.error("支付宝H5下单失败", e);
            aliPrePayResponse.setCode(BusinessConstant.PAY_REQUEST_FAIL);
            aliPrePayResponse.setMsg("失败");
            return aliPrePayResponse;
        }

        aliPrePayResponse.setResult(alipayRequestUrl);
        aliPrePayResponse.setCode(BusinessConstant.PAY_REQUEST_SUCCESS);
        aliPrePayResponse.setMsg("成功");
        logger.info("支付宝支付返回:" + JSON.toJSONString(aliPrePayResponse));

        return aliPrePayResponse;
    }

    /**
     * 支付宝支付下单
     *
     * @param paramMap 参数
     * @return 返回结果
     */
    private AliPrePayResponse alipayApp(final Map<String, String> paramMap) {
        AliPrePayResponse aliPrePayResponse = new AliPrePayResponse();

        AlipayClient alipayClient = new DefaultAlipayClient(AliPayConfig.ALIPAY_URL, AliPayConfig.app_id, AliPayConfig.private_key, AliPayConfig.FORMAT, AliPayConfig.input_charset, AliPayConfig.public_key, AliPayConfig.sign_type_2);

        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody(AliPayConfig.GOODS_APP_DETAIL);
        model.setSubject(MessageFormat.format(AliPayConfig.GOODS_APP_NAME, paramMap.get("payPaymentNo")));
        model.setOutTradeNo(paramMap.get("payPaymentNo"));
        model.setTimeoutExpress(AliPayConfig.TIMEOUT_EXPRESS);
        model.setTotalAmount(paramMap.get("payAmount"));
        model.setProductCode(AliPayConfig.PRODUCT_CODE);
        request.setBizModel(model);
        request.setNotifyUrl(notifyUrl);
        //构造请求(签名)
        String alipayRequestUrl;
        try {
            //这里和普通的接口调用不同，使用的是sdkExecute
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            logger.info(response.isSuccess() + "," + response.getCode() + "," + response.getMsg());
            if (response.isSuccess()) {
                alipayRequestUrl = response.getBody();
            } else {
                throw new AlipayApiException("alipay exception");
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            aliPrePayResponse.setCode(BusinessConstant.PAY_REQUEST_FAIL);
            aliPrePayResponse.setMsg("失败");
            return aliPrePayResponse;
        }

        aliPrePayResponse.setResult(alipayRequestUrl);
        aliPrePayResponse.setCode(BusinessConstant.PAY_REQUEST_SUCCESS);
        aliPrePayResponse.setMsg("成功");
        logger.info("支付宝支付返回:" + JSON.toJSONString(aliPrePayResponse));

        return aliPrePayResponse;
    }

//    /**
//     * 支付宝H5支付下单
//     *
//     * @param paramMap 参数
//     * @return 返回参数
//     */
//    private AliPrePayResponse alipayH5_old(final Map<String, String> paramMap) {
//        AliPrePayResponse aliPrePayResponse = new AliPrePayResponse();
//        //组装报文
//        Map<String, String> alipayBodyMap = new HashMap<>(15);
//        alipayBodyMap.put("service", AliPayConfig.service);
//        alipayBodyMap.put("partner", AliPayConfig.partner);
//        alipayBodyMap.put("_input_charset", AliPayConfig.input_charset);
//        alipayBodyMap.put("notify_url", AliPayConfig.notify_url);
//        alipayBodyMap.put("return_url", paramMap.get("returnUrl"));
//        alipayBodyMap.put("out_trade_no", paramMap.get("payPaymentNo"));
//        alipayBodyMap.put("subject", AliPayConfig.GOODS_NAME);
//        alipayBodyMap.put("total_fee", paramMap.get("payAmount"));
//        alipayBodyMap.put("seller_id", AliPayConfig.seller_id);
//        alipayBodyMap.put("payment_type", AliPayConfig.payment_type);
//        //构造请求(签名)
//        String alipayRequestUrl;
//        try {
//            logger.info("支付宝下单参数 {}", JSON.toJSONString(alipayBodyMap));
//            alipayRequestUrl = AlipaySubmit.buildRequestUrl(AliPayConfig.ALIPAY_GATEWAY_NEW, alipayBodyMap);
//        } catch (Exception e) {
//            logger.error("支付宝 payPaymentNo is : " + paramMap.get("payPaymentNo") + "支付失败", e);
//            aliPrePayResponse.setCode(BusinessConstant.PAY_REQUEST_FAIL);
//            aliPrePayResponse.setMsg("失败");
//            return aliPrePayResponse;
//        }
//        aliPrePayResponse.setResult(alipayRequestUrl);
//        aliPrePayResponse.setCode(BusinessConstant.PAY_REQUEST_SUCCESS);
//        aliPrePayResponse.setMsg("成功");
//        logger.info("支付宝支付返回:" + JSON.toJSONString(aliPrePayResponse));
//
//        return aliPrePayResponse;
//    }

//    /**
//     * 支付宝支付下单
//     *
//     * @param paramMap 参数
//     * @return 返回参数
//     */
//    private AliPrePayResponse alipayApp_old(final Map<String, String> paramMap) {
//        AliPrePayResponse aliPrePayResponse = new AliPrePayResponse();
//
//        //组装报文
//        Map<String, String> alipayBodyMap = new HashMap<>(15);
//        alipayBodyMap.put("service", AliPayConfig.service);
//        alipayBodyMap.put("partner", AliPayConfig.partner);
//        alipayBodyMap.put("_input_charset", AliPayConfig.input_charset);
//        alipayBodyMap.put("notify_url", AliPayConfig.notify_url);
//        alipayBodyMap.put("return_url", paramMap.get("returnUrl"));
//        alipayBodyMap.put("out_trade_no", paramMap.get("payPaymentNo"));
//        alipayBodyMap.put("subject", MessageFormat.format(AliPayConfig.GOODS_APP_NAME, paramMap.get("payPaymentNo")));
//        alipayBodyMap.put("body", AliPayConfig.GOODS_APP_DETAIL);
//        alipayBodyMap.put("total_fee", paramMap.get("payAmount"));
//        alipayBodyMap.put("seller_id", AliPayConfig.seller_id_new);
//        alipayBodyMap.put("payment_type", AliPayConfig.payment_type);
//        //构造请求(签名)
//        String alipayRequestUrl;
//        try {
//            logger.info("支付宝下单参数 {}", JSON.toJSONString(alipayBodyMap));
//            alipayRequestUrl = AlipaySubmit.buildRequestUrl(alipayBodyMap);
//        } catch (Exception e) {
//            logger.error("支付宝 payPaymentNo is : " + paramMap.get("payPaymentNo") + "支付失败", e);
//            aliPrePayResponse.setCode(BusinessConstant.PAY_REQUEST_FAIL);
//            aliPrePayResponse.setMsg("失败");
//            return aliPrePayResponse;
//        }
//        aliPrePayResponse.setResult(alipayRequestUrl);
//        aliPrePayResponse.setCode(BusinessConstant.PAY_REQUEST_SUCCESS);
//        aliPrePayResponse.setMsg("成功");
//        logger.info("支付宝支付返回:" + JSON.toJSONString(aliPrePayResponse));
//
//        return aliPrePayResponse;
//    }
}
